
#include "flash.h"
#include "alloc.h"
#include "uart.h"
#include "self_programming.h"

#if(TEST_IN_HOST == 0)
#include <avr/pgmspace.h>
#endif

static st_sensor_fdata*	g_mempoolf_start_addr = NULL;
static u08		g_mempoolf_cur_idx = 0;
static u08		g_mempoolf_tot_cnt = 0;

static st_sensor_mdata*	g_mempoolm_start_addr = NULL;
static u08		g_mempoolm_cur_idx = 0;
static u08		g_mempoolm_tot_cnt = 0;

#define DEBUG_SB  0
void mempool_deinit(void)
{
	g_mempoolf_start_addr = NULL;
	g_mempoolf_cur_idx = 0;
	g_mempoolf_tot_cnt = 0;

	g_mempoolm_start_addr = NULL;
	g_mempoolm_cur_idx = 0;
	g_mempoolm_tot_cnt = 0;

}
//---------------------------------------------------------------------------------------
void mempool_sensor_fdata_init(u08*start_addr,u16 unit_cnt)
{
	g_mempoolf_cur_idx = 0;
	g_mempoolf_tot_cnt = unit_cnt;
	g_mempoolf_start_addr = (st_sensor_fdata*)start_addr;

	return;
}

st_sensor_fdata* mempool_sensor_fdata_get(void)
{
	st_sensor_fdata* p = NULL;
	if(g_mempoolf_cur_idx<g_mempoolf_tot_cnt)
	{
		p = &g_mempoolf_start_addr[g_mempoolf_cur_idx];
		g_mempoolf_cur_idx++;
	}
	return p;
}
//---------------------------------------------------------------------------------------
void mempool_sensor_mdata_init(u08*start_addr,u16 unit_cnt)
{
	g_mempoolm_cur_idx = 0;
	g_mempoolm_tot_cnt = unit_cnt;
	g_mempoolm_start_addr = (st_sensor_mdata*)start_addr;

	return;
}

st_sensor_mdata* mempool_sensor_mdata_get(void)
{
	st_sensor_mdata* p = NULL;
	if(g_mempoolm_cur_idx<g_mempoolm_tot_cnt)
	{
		p = &g_mempoolm_start_addr[g_mempoolm_cur_idx];
		g_mempoolm_cur_idx++;
	}
	return p;
}
//---------------------------------------------------------------------------------------

/*
   typedef struct _st_flash_superblock
   {
   u32 dummy;
   u08	programed;
   u08	flag_test[3];
   u16	programed_cnt;
   u16	sensor_cnt;
   u16 page_start;
   u16 page_end;
   }st_flash_sb;
   */
void flash_sb_init(st_flash_sb*sb)
{
	u32 ptr;
	u32 dummy;

	ptr = (u32)FLASH_ADDR_SUPER_BLOCK*FLASH_PAGE_SIZE;
        
	dummy = ReadFlashByte(ptr++);
	dummy |= ((u32)ReadFlashByte(ptr++)<<8);
	dummy |= ((u32)ReadFlashByte(ptr++)<<16);
	dummy |= ((u32)ReadFlashByte(ptr++)<<24);

	if(dummy == SUPER_BLOCK_DUMMY)
	{
        
		sb->dummy = dummy;

		sb->programed = ReadFlashByte(ptr++);

		sb->flag_test[0] = ReadFlashByte(ptr++);
		sb->flag_test[1] = ReadFlashByte(ptr++);
		sb->flag_test[2] = ReadFlashByte(ptr++);

		sb->programed_cnt = ReadFlashByte(ptr++);
		sb->programed_cnt |= (ReadFlashByte(ptr++)<<8);

		sb->sensor_cnt = ReadFlashByte(ptr++);
		sb->sensor_cnt |= (ReadFlashByte(ptr++)<<8);

		sb->page_start = ReadFlashByte(ptr++);
		sb->page_start |= (ReadFlashByte(ptr++)<<8);

		sb->page_end = ReadFlashByte(ptr++);
		sb->page_end |= (ReadFlashByte(ptr++)<<8);

	}
	else
	{
		sb->dummy = SUPER_BLOCK_DUMMY;
		sb->programed = 0x00;//FLAG_FLASH_PROGRAMED;
		sb->flag_test[0]  = 0x00;
		sb->flag_test[1]  = 0x00;
		sb->flag_test[2]  = 0x00;
		sb->programed_cnt = 0x00;
		sb->sensor_cnt = 0;
		sb->page_start = FLASH_ADDR_SUPER_BLOCK+1;
		sb->page_end = FLASH_ADDR_SUPER_BLOCK+1;		
	}
    

    
#if(DEBUG_SB == 1)
    F(("rsb:%lx %lx\r\n",(u32)FLASH_ADDR_SUPER_BLOCK*FLASH_PAGE_SIZE,ptr));
    F(("sb->dummy=%lx\r\n",sb->dummy));
    F(("sb->p=%x\r\n",sb->programed));
    F(("sb->pcnt=%x\r\n",sb->programed_cnt));
    F(("sb->scnt=%x\r\n",sb->sensor_cnt));
    F(("sb->ps=%x\r\n",sb->page_start));
    F(("sb->pe=%x\r\n",sb->page_end));
#endif

	return ;
}

s16	flash_sb_rewrite(st_flash_sb*sb)
{
	u08*pdst,*psrc;
	s16	ret = ERR_NO_ERR;
	u16	i;
	u32 ptr ;
	//------------------------------------------
    sb->programed = FLAG_FLASH_PROGRAMED;
	sb->programed_cnt++;
	//------------------------------------------	
	pdst = user_malloc_alloc(FLASH_PAGE_SIZE);
	if(pdst == NULL)
	{
		return -1;
	}
	for(i = 0;i<FLASH_PAGE_SIZE;i++)
		pdst[i] = 0x00;

	psrc = (u08*)sb;
	for(i = 0;i<sizeof(st_flash_sb);i++)
		pdst[i] = psrc[i];

	ptr = FLASH_ADDR_SUPER_BLOCK*(u32)FLASH_PAGE_SIZE;
	
        
#if(DEBUG_SB == 1)
    F(("wsb:%lx\r\n",ptr));
    F(("sb->dummy=%lx\r\n",sb->dummy));
    F(("sb->p=%x\r\n",  sb->programed));
    F(("sb->pcnt=%x\r\n",sb->programed_cnt));
    F(("sb->scnt=%x\r\n",sb->sensor_cnt));
    F(("sb->ps=%x\r\n",sb->page_start));
    F(("sb->pe=%x\r\n",sb->page_end));
    for(i = 0;i<sizeof(st_flash_sb);i++)
        F(("%x ",pdst[i]));
    F(("\r\n"));
#endif
    
    if(WriteFlashPage(ptr,pdst) == FALSE)
    {
        ret = -2;
    }

	user_malloc_free(pdst);

	return ret;
}


